/* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.wdullaer.materialdatetimepicker.date; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.ViewGroup; import android.widget.AbsListView.LayoutParams; import com.wdullaer.materialdatetimepicker.date.MonthAdapter.MonthViewHolder; import com.wdullaer.materialdatetimepicker.date.MonthView.OnDayClickListener; import java.util.Calendar; import java.util.TimeZone; /** * An adapter for a list of {@link MonthView} items. */ @SuppressWarnings("WeakerAccess") public abstract class MonthAdapter extends RecyclerView.Adapter<MonthViewHolder> implements OnDayClickListener { protected final DatePickerController mController; private CalendarDay mSelectedDay; protected static int WEEK_7_OVERHANG_HEIGHT = 7; protected static final int MONTHS_IN_YEAR = 12; /** * A convenience class to represent a specific date. */ public static class CalendarDay { private Calendar calendar; int year; int month; int day; TimeZone mTimeZone; public CalendarDay(TimeZone timeZone) { mTimeZone = timeZone; setTime(System.currentTimeMillis()); } public CalendarDay(long timeInMillis, TimeZone timeZone) { mTimeZone = timeZone; setTime(timeInMillis); } public CalendarDay(Calendar calendar, TimeZone timeZone) { mTimeZone = timeZone; year = calendar.get(Calendar.YEAR); month = calendar.get(Calendar.MONTH); day = calendar.get(Calendar.DAY_OF_MONTH); } public CalendarDay(int year, int month, int day) { setDay(year, month, day); } public void set(CalendarDay date) { year = date.year; month = date.month; day = date.day; } public void setDay(int year, int month, int day) { this.year = year; this.month = month; this.day = day; } private void setTime(long timeInMillis) { if (calendar == null) { calendar = Calendar.getInstance(mTimeZone); } calendar.setTimeInMillis(timeInMillis); month = calendar.get(Calendar.MONTH); year = calendar.get(Calendar.YEAR); day = calendar.get(Calendar.DAY_OF_MONTH); } public int getYear() { return year; } public int getMonth() { return month; } public int getDay() { return day; } } public MonthAdapter(DatePickerController controller) { mController = controller; init(); setSelectedDay(mController.getSelectedDay()); setHasStableIds(true); } /** * Updates the selected day and related parameters. * * @param day The day to highlight */ public void setSelectedDay(CalendarDay day) { mSelectedDay = day; notifyDataSetChanged(); } @SuppressWarnings("unused") public CalendarDay getSelectedDay() { return mSelectedDay; } /** * Set up the gesture detector and selected time */ protected void init() { mSelectedDay = new CalendarDay(System.currentTimeMillis(), mController.getTimeZone()); } @Override public MonthViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { MonthView v = createMonthView(parent.getContext()); // Set up the new view LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); v.setLayoutParams(params); v.setClickable(true); v.setOnDayClickListener(this); return new MonthViewHolder(v); } @Override public void onBindViewHolder(MonthViewHolder holder, int position) { holder.bind(position, mController, mSelectedDay); } @Override public long getItemId(int position) { return position; } @Override public int getItemCount() { Calendar endDate = mController.getEndDate(); Calendar startDate = mController.getStartDate(); int endMonth = endDate.get(Calendar.YEAR) * MONTHS_IN_YEAR + endDate.get(Calendar.MONTH); int startMonth = startDate.get(Calendar.YEAR) * MONTHS_IN_YEAR + startDate.get(Calendar.MONTH); return endMonth - startMonth + 1; //return ((mController.getMaxYear() - mController.getMinYear()) + 1) * MONTHS_IN_YEAR; } public abstract MonthView createMonthView(Context context); @Override public void onDayClick(MonthView view, CalendarDay day) { if (day != null) { onDayTapped(day); } } /** * Maintains the same hour/min/sec but moves the day to the tapped day. * * @param day The day that was tapped */ protected void onDayTapped(CalendarDay day) { mController.tryVibrate(); mController.onDayOfMonthSelected(day.year, day.month, day.day); setSelectedDay(day); } static class MonthViewHolder extends RecyclerView.ViewHolder { public MonthViewHolder(MonthView itemView) { super(itemView); } void bind(int position, DatePickerController mController, CalendarDay selectedCalendarDay) { final int month = (position + mController.getStartDate().get(Calendar.MONTH)) % MONTHS_IN_YEAR; final int year = (position + mController.getStartDate().get(Calendar.MONTH)) / MONTHS_IN_YEAR + mController.getMinYear(); int selectedDay = -1; if (isSelectedDayInMonth(selectedCalendarDay, year, month)) { selectedDay = selectedCalendarDay.day; } ((MonthView) itemView).setMonthParams(selectedDay, year, month, mController.getFirstDayOfWeek()); this.itemView.invalidate(); } private boolean isSelectedDayInMonth(CalendarDay selectedDay, int year, int month) { return selectedDay.year == year && selectedDay.month == month; } } }